package com.lagou.client;


import com.lagou.NettyConnection;
import com.lagou.RpcRequest;
import com.lagou.export.RpcExportUtils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RpcConsumer {

    //创建线程池对象
    private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    private static UserClientHandler userClientHandler;

    //1.创建一个代理对象 providerName：UserService#sayHello are you ok?
    public Object createProxy(final Class<?> serviceClass,final String providerName){
        //借助JDK动态代理生成代理对象
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{serviceClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                //获取负载均衡 获取最后一次响应时间短的
                ClientConnection connection = getClientConnection();
                // 设置参数
                RpcRequest request = new RpcRequest();
                request.setParameters(args);
                request.setMethodName(method.getName());
                request.setClassName(serviceClass.getName());
                request.setParameterTypes(method.getParameterTypes());
                connection.getUserClientHandler().setPara(request);

                // 去服务端请求数据
                Object obj = null;
                try {
                    obj = executor.submit(connection.getUserClientHandler()).get();
                    System.out.println(connection.getIp() + ":" + connection.getPort() + ":" + obj);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println(connection.getPort() + ":" + e.getMessage());
                }


                return obj;


            }
        });

    }

    /**
     *  获取时间最短的一个 connection
     * @return
     */
    private ClientConnection getClientConnection() {
        ClientConnection connection = null;
        Map<String,Integer> serverTimeMap = new HashMap();
        List<Integer> runTimeList = new ArrayList<>();
        for (Map.Entry<String, ? extends NettyConnection> ev : RpcExportUtils.getMap().entrySet()) {
            System.out.println(ev.getKey());
            connection = (ClientConnection) ev.getValue();
            if (ev.getValue() == null) {
                connection = ClientUtils.initClient(ev.getKey());

                RpcExportUtils.CONNECTION_MAP.put(ev.getKey(), connection);

                RpcExportUtils.addListener(RpcExportUtils.CONNECTION_MAP);

            }
            Long timestamp = connection.getTimestamp();
            if(timestamp != null && timestamp > 0L){
                //超过5s有效期则清空
                if(System.currentTimeMillis() - timestamp > 5000){
                    timestamp = 0L;
                    ((ClientConnection) ev.getValue()).setTimestamp(System.currentTimeMillis());
                }
                serverTimeMap.put(ev.getKey(),timestamp.intValue());
            }else{
                serverTimeMap.put(ev.getKey(),0);
                timestamp = 0L;
            }
            runTimeList.add(timestamp.intValue());
        }
        if(serverTimeMap.size() != 0 ){

            Integer min = Collections.min(runTimeList);
            List<String> serverNameList = new ArrayList<String>();
            serverTimeMap.forEach((key, value) -> {
                if(value.equals(min)){
                    serverNameList.add(key);
                }
            });
            //如果时间有一致的随机
            Random random = new Random();

            int n = random.nextInt(serverNameList.size());
            String key = serverNameList.get(n);
            System.out.println("选择服务：" + key);
            return (ClientConnection) RpcExportUtils.getMap().get(key);
        }

        return null;
    }
}
